//
//Copyright 2001-2004 Stottler Henke Associates, Inc.
//All Rights Reserved.
////////////////////////////////////////////////////////////////////////////////

package com.stottlerhenke.simbionic.engine.parser;

import com.stottlerhenke.simbionic.engine.*;
import com.stottlerhenke.simbionic.engine.file.SB_StreamReader;
import com.stottlerhenke.simbionic.api.*;
import com.stottlerhenke.simbionic.api.SB_Param;

/**
 * Represents a single variable of type vector.
 */
public class SB_VarVector extends SB_Variable 
{

  public SB_VarVector() {
    _parameterValue = new SB_Param( 0.0f, 0.0f, 0.0f );
  }
  
  public SB_VarVector(float x, float y, float z){
    _parameterValue = new SB_Param( x, y, z );
  }
  
  public SB_VarVector(SB_Vector var){
    _parameterValue = new SB_Param( var.x, var.y, var.z );
  }
  
  public SB_VarVector(SB_VarVector var)
  throws SB_Exception
  {
   Copy(var);
  }
  
  private void Copy( SB_VarVector var) 
  throws SB_Exception
  {
    _parameterValue = new SB_Param( var.GetValue().x, var.GetValue().y, var.GetValue().z );
  }

  public void SetValue( SB_Vector value){
    _parameterValue.setVector( value.x, value.y, value.z );
  }
  public SB_Vector GetValue() throws SB_Exception
  {
    return new SB_Vector( _parameterValue.getVector().x, _parameterValue.getVector().y, _parameterValue.getVector().z );
  }
  
  public SB_VarType GetType() { return SB_VarType.kVector; }
  
  public void setSB_Param(SB_Param newParam) throws SB_Exception
  {
    newParam.getVector();
    
    _parameterValue = newParam;
  }
  
  public SB_Variable opAssign( SB_VarVector var) 
  throws SB_Exception
  {
    if (this != var) {
      Copy(var);
    }
    return this;
  }

  public SB_Variable Clone() throws SB_Exception {
    return new SB_VarVector(this);
  }

  /**
   * We need to be able to load:
   *
   * [4 4 4]
   * [4,4,4]
   * [4, 4, 4]
   * @param tokenizer
   */
  public void load(SB_StreamReader reader,SB_SingletonBook book)
		throws SB_Exception
  {
    SetValue( reader.readVector() );
  }

  public static SB_Vector GET_VECTOR(SB_Variable var)
  throws SB_Exception
  {
    return ((SB_VarVector)var).GetValue();
  }
  
  public SB_Variable opOR( SB_Variable arg2)  {
    //FATAL( false, "Invalid operation on vector variable");
    return null;
  }

  public SB_Variable opAND( SB_Variable arg2) throws SB_Exception  {
    //FATAL( false, "Invalid operation on vector variable");
    return null;
  }

  public SB_Variable opGRTEq( SB_Variable arg2) throws SB_Exception  {
    //FATAL( false, "Invalid operation on vector variable");
    return null;
  }

  public SB_Variable opLSSEq( SB_Variable arg2) throws SB_Exception  {
    //FATAL( false, "Invalid operation on vector variable");
    return null;
  }

  public SB_Variable opNOTEq( SB_Variable arg2) throws SB_Exception  {
    SB_Variable result = null;

    if(arg2.GetType() == SB_VarType.kVector){
      SB_Vector vec = GET_VECTOR(arg2);
      result = new SB_VarBoolean( (GetValue().x != vec.x) || (GetValue().y != vec.y) || (GetValue().z != vec.z) );
    }
    else if (arg2.GetType() == SB_VarType.kInvalid)
      result = new SB_VarBoolean( true );
    return result;
  }

  public SB_Variable equals( SB_Variable arg2) throws SB_Exception  {
    SB_Variable result = null;

    if(arg2.GetType() == SB_VarType.kVector){
      SB_Vector vec = GET_VECTOR(arg2);
      result = new SB_VarBoolean( (GetValue().x == vec.x) && (GetValue().y == vec.y) && (GetValue().z == vec.z) );
    }
    else if(arg2.GetType() == SB_VarType.kInvalid)
      result = new SB_VarBoolean( false );
    return result;
  }

  public SB_Variable opGRT( SB_Variable arg2) throws SB_Exception  {
    //FATAL( false, "Invalid operation on vector variable");
    return null;
  }

  public SB_Variable opLSS( SB_Variable arg2) throws SB_Exception  {
    //FATAL( false, "Invalid operation on vector variable");
    return null;
  }

  public SB_Variable opMOD( SB_Variable arg2) throws SB_Exception  {
    //FATAL( false, "Invalid operation on vector variable");
    return null;
  }

  public SB_Variable opEXP( SB_Variable arg2) throws SB_Exception  {
    //FATAL( false, "Invalid operation on vector variable");
    return null;
  }

  public SB_Variable opDIV( SB_Variable arg2) throws SB_Exception  {
    SB_Variable result = null;

    if(arg2.GetType() == SB_VarType.kVector){
      SB_Vector vec = GET_VECTOR(arg2);
      result = new SB_VarVector( GetValue().x / vec.x, GetValue().y / vec.y, GetValue().z / vec.z );
    }
    else if(arg2.GetType() == SB_VarType.kFloat){
      float scalar = SB_VarFloat.GET_FLOAT(arg2);
      result = new SB_VarVector( GetValue().opDIV( scalar) );
    }
    else if(arg2.GetType() == SB_VarType.kInteger){
      int scalar = SB_VarInteger.GET_INTEGER(arg2);
      result = new SB_VarVector( GetValue().opDIV (scalar) );
    }
    return result;
  }

  public SB_Variable opMUL( SB_Variable arg2) throws SB_Exception  {
    SB_Variable result = null;

    if (arg2.GetType() == SB_VarType.kVector){
      SB_Vector vec = GET_VECTOR(arg2);
      result = new SB_VarVector( GetValue().x * vec.x, GetValue().y * vec.y,GetValue().z * vec.z );
    }
    else if(arg2.GetType() == SB_VarType.kFloat){
      float scalar = SB_VarFloat.GET_FLOAT(arg2);
      result = new SB_VarVector( GetValue().opMUL( scalar) );
    }
    else if(arg2.GetType() == SB_VarType.kInteger){
      int scalar = SB_VarInteger.GET_INTEGER(arg2);
      result = new SB_VarVector( GetValue().opMUL( scalar) );
    }
    return result;
  }

  public SB_Variable opSUB( SB_Variable arg2) throws SB_Exception  {
    SB_Variable result = null;

    if (arg2.GetType()==SB_VarType.kVector)
       result = new SB_VarVector( GetValue().opSUB(GET_VECTOR(arg2)) );
     return result;
  }

  public SB_Variable opADD( SB_Variable arg2) throws SB_Exception  {
    SB_Variable result = null;

    if(arg2.GetType() == SB_VarType.kVector)
      result = new SB_VarVector( GetValue().opAdd(GET_VECTOR(arg2)) );
    else if(arg2.GetType() == SB_VarType.kString)	// returns a concatenated string
    {
      String workStr;
      workStr = "["+ Float.toString(GetValue().x) + ","+ Float.toString( GetValue().y) + "," + Float.toString( GetValue().z) + "]" + SB_VarString.GET_STRING(arg2);
      result = new SB_VarString( workStr );
     }
     return result;
  }

  public SB_Variable opNOT() throws SB_Exception  {
    return new SB_VarBoolean(GetValue().x == 0 && GetValue().y == 0 && GetValue().z == 0);
  }

  public SB_Variable opNEG() throws SB_Exception  {
    SB_Variable result = null;
    result = new SB_VarVector( -GetValue().x, -GetValue().y, -GetValue().z );
    return result;
  }

  public boolean bool() throws SB_Exception
  {
    return GetValue().x != 0 || GetValue().y != 0 || GetValue().z != 0;
  }

  public String toString()
  {
    try
    {
	    String outStr;
	    if (GetValue() != null)
	    {
	      outStr = "[" + Float.toString(GetValue().x) + "," + Float.toString(GetValue().y) + ", " + Float.toString(GetValue().z) + "]";
	    }else
	    {
	       outStr = "[-,-,-]";
	    }
	    return outStr;
    }
    catch(SB_Exception ex)
    {
      return ex.toString();
    }
  }

}